package net.kazed.nextaction.database.serialize;

import java.util.HashMap;
import java.util.Map;

import net.kazed.nextaction.database.Task;

import org.xml.sax.Attributes;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;

public class TaskHandler extends AbstractElementHandler implements ElementHandlerContext<RestoreTask> {

    private ContentResolver contentResolver;
    private RestoreTask currentTask;
    private Map<Integer, Integer> contextIdTranslation;
    private Map<Integer, Integer> taskIdTranslation;

    public TaskHandler(ContentResolver contentResolver, Map<Integer, Integer> contextIdTranslation) {
        super();
        this.contentResolver = contentResolver;
        this.contextIdTranslation = contextIdTranslation;
        this.taskIdTranslation = new HashMap<Integer, Integer>();
        
        addElementHandler("id", new TaskHandler.TaskIdHandler(this));
        addElementHandler("description", new TaskHandler.TaskDescriptionHandler(this));
        addElementHandler("parentTaskId", new TaskHandler.TaskParentTaskIdHandler(this));
        addElementHandler("details", new TaskHandler.TaskDetailsHandler(this));
        addElementHandler("contextId", new TaskHandler.TaskContextIdHandler(this));
        addElementHandler("complete", new TaskHandler.TaskCompleteHandler(this));
    }

    public RestoreTask getCurrentTask() {
        return currentTask;
    }

    @Override
    public void startElement(String name, Attributes attributes,
            ParserState state) {
        currentTask = new RestoreTask();
    }

    @Override
    public void endElement(String name, ParserState state) {
        Integer contextId = contextIdTranslation.get(currentTask.contextId);
        if (contextId == null) {
            contextId = currentTask.contextId;
        }
        
        Task task = new Task(currentTask.id, currentTask.description, currentTask.details, contextId,
                currentTask.parentTaskId, currentTask.created, currentTask.modified, currentTask.startDate,
                currentTask.dueDate, currentTask.order, currentTask.completed);
        ContentValues values = new ContentValues();
        task.toValues(values);
        Uri itemUri = ContentUris.withAppendedId(Task.CONTENT_URI, task.getId());
        int count = contentResolver.update(itemUri, values, null, null);
        if (count == 0) {
            Uri newTaskUri = contentResolver.insert(Task.CONTENT_URI, values);
            String idSegment = newTaskUri.getLastPathSegment();
            Integer newTaskId = Integer.valueOf(idSegment);
            taskIdTranslation.put(currentTask.id, newTaskId);
        } else {
            contentResolver.update(itemUri, values, null, null);
            taskIdTranslation.put(currentTask.id, currentTask.id);
        }
        currentTask = null;
    }
    
    @Override
    public RestoreTask getContextData() {
        return currentTask;
    }

    public static class TaskIdHandler extends AbstractElementHandlerWithContext<RestoreTask> {
        public TaskIdHandler(ElementHandlerContext<RestoreTask> handlerContext) {
            super(handlerContext);
        }
        @Override
        public void characters(String text, ParserState state) {
            getContextData().id = Integer.valueOf(text);
        }
    }
    
    public static class TaskDescriptionHandler extends AbstractElementHandlerWithContext<RestoreTask> {
        public TaskDescriptionHandler(ElementHandlerContext<RestoreTask> handlerContext) {
            super(handlerContext);
        }
        @Override
        public void characters(String text, ParserState state) {
            getContextData().description = text;
        }
        @Override
        public boolean isValueEncoded() {
            return true;
        }
    }
    
    public static class TaskDetailsHandler extends AbstractElementHandlerWithContext<RestoreTask> {
        public TaskDetailsHandler(ElementHandlerContext<RestoreTask> handlerContext) {
            super(handlerContext);
        }
        @Override
        public void characters(String text, ParserState state) {
            getContextData().details = text;
        }
        @Override
        public boolean isValueEncoded() {
            return true;
        }
    }
    
    public static class TaskParentTaskIdHandler extends AbstractElementHandlerWithContext<RestoreTask> {
        public TaskParentTaskIdHandler(ElementHandlerContext<RestoreTask> handlerContext) {
            super(handlerContext);
        }
        @Override
        public void characters(String text, ParserState state) {
            getContextData().parentTaskId = Integer.valueOf(text);
        }
    }

    public static class TaskContextIdHandler extends AbstractElementHandlerWithContext<RestoreTask> {
        public TaskContextIdHandler(ElementHandlerContext<RestoreTask> handlerContext) {
            super(handlerContext);
        }
        @Override
        public void characters(String text, ParserState state) {
            getContextData().contextId = Integer.valueOf(text);
        }
    }

    public static class TaskCompleteHandler extends AbstractElementHandlerWithContext<RestoreTask> {
        public TaskCompleteHandler(ElementHandlerContext<RestoreTask> handlerContext) {
            super(handlerContext);
        }
        @Override
        public void characters(String text, ParserState state) {
            getContextData().completed = Boolean.parseBoolean(text);
        }
    }

}
